package com.jack.reentrantLock;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockTest {

    static ReentrantLock lock = new ReentrantLock(true);

    static int num;


    public static void main(String[] args) throws InterruptedException {

        CountDownLatch latch = new CountDownLatch(1);

        for (int i = 0; i < 50; i++) {

            Thread t = new Thread(new MyRunnable(latch));
            t.setName("t"+i);
            t.start();
        }

        Thread.sleep(100);

        System.out.println("开始竞争");
        latch.countDown();

    }

     static class MyRunnable implements Runnable{

        CountDownLatch latch;

        public MyRunnable(CountDownLatch latch) {
            this.latch = latch;
        }

        @Override
        public void run() {
            try {
//                System.out.println(Thread.currentThread().getName()+" 等待竞争");
//                latch.await();

                lock.lock();
                System.out.println(Thread.currentThread().getName()+" 已锁");
                testSycn();
            }
//            catch (InterruptedException e) {
//                e.printStackTrace();
//            }
            finally {

                System.out.println(Thread.currentThread().getName()+" 释放锁");
                lock.unlock();

                //有个问题：lock 到 unlock不是只能是同一个线程执行结束（解锁）才能到另一个线程继续执行吗。
                //为什么在释放锁之前有几个线程已经执行完了。
                /**
                 * t0 已锁
                 * thread t0 计算结果 = 1
                 * t1 已锁
                 * thread t1 计算结果 = 2
                 * t2 已锁
                 * thread t2 计算结果 = 3
                 * t3 已锁
                 * thread t3 计算结果 = 4
                 * t1 已释放锁
                 * t4 已锁
                 * t2 已释放锁
                 * thread t4 计算结果 = 5
                 * t4 已释放锁
                 * t5 已锁
                 * t3 已释放锁
                 * thread t5 计算结果 = 6
                 * t5 已释放锁
                 * t6 已锁
                 * t0 已释放锁
                 **/
                // 原来我把打印的代码在unlock执行后，这样会导致打印有可能出现在其他线程执行完成之后再执行。
                // 所以把打印放到unlock之前就不会出现这个问题。
                /**
                 * t1 已锁
                 * thread t1 计算结果 = 1
                 * t1 释放锁
                 * t0 已锁
                 * thread t0 计算结果 = 2
                 * t0 释放锁
                 * t2 已锁
                 * thread t2 计算结果 = 3
                 * t2 释放锁
                 * t4 已锁
                 * thread t4 计算结果 = 4
                 * t4 释放锁
                 * t3 已锁
                 * thread t3 计算结果 = 5
                 * t3 释放锁
                 * t5 已锁
                 * thread t5 计算结果 = 6
                 * t5 释放锁
                 *
                 **/
            }

        }
    }


    private static void testSycn(){

        num++;

        System.out.println("thread "+ Thread.currentThread().getName() +" 计算结果 = "+num);


    }



}
